#ifndef DATABASEMANAGER_H
#define DATABASEMANAGER_H

#include <QObject>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QString>
#include <QStringList>
#include <QVariant>
#include <QStandardPaths>
#include <QDir>
#include <QDebug>

// 网盘记录结构体
struct KmsDisk {
    QString id;
    int type;
    QString name;
    QString domainId;
    QString ownerId;
    int orderNo;
};

// 文件夹记录结构体
struct KmsFolder {
    QString id;
    QString name;
    QString diskId;
    QString folderId;
    QString path;
    QString creator;
    QString creatorId;
    int type;
    QString createDate;
    QString lastModifyDate;
    int orderNo;
    QString removeOperator;
    int status;      // 文件夹状态：-1-标记删除；0-标记未同步；1-标记已同步
    int version;     // 文件夹版本
    int maxVersion;  // 文件夹最大版本
};

// 文件记录结构体
struct KmsFile {
    QString id;
    QString name;
    QString diskId;
    QString folderId;
    QString creator;
    QString creatorId;
    QString type;
    QString createDate;
    QString lastModifyDate;
    int originType;
    QString originId;
    qint64 size;           // 文件大小
    QString removeOperator;
    int status;         // 文件状态：-1-标记删除；0-标记未同步；1-标记已同步
    QString checksum;   // SHA-1校验和
    qint64 localFileSize;    // 本地文件大小，默认值为0
    QString localFileChecksum; // 本地文件校验和，默认值为null
    QString localFilePath;    // 本地文件路径（相对于工作目录的路径）
};

// 命令记录结构体
struct KmsCommand {
    QString id;
    QString createDate;
    QString localFilePath;
    QString downloadUrl;
    QString commitUrl;
    QString accessToken;
    QString command;
};

class DatabaseManager : public QObject
{
    Q_OBJECT

public:
    explicit DatabaseManager(QObject *parent = nullptr);
    ~DatabaseManager();

    // 初始化数据库连接
    bool initializeDatabase();
    
    // 设置数据库路径并重新初始化
    bool setDatabasePath(const QString &path);
    
    // 设置用户工作目录并自动设置数据库路径
    Q_INVOKABLE bool setUserWorkDirectoryAndDatabase(const QString &workDirectory);
    
    // 测试方法：插入测试文件夹数据
    Q_INVOKABLE void insertTestFolderData();
    
    // 网盘记录操作
    bool insertDisk(const KmsDisk &disk);
    bool updateDisk(const KmsDisk &disk);
    QList<KmsDisk> queryDisksByName(const QString &name);
    QList<KmsDisk> queryAllDisks();
    bool syncDisksFromJson(const QJsonArray &disksData);
    
    // 同步文件夹数据
    bool syncFoldersFromJson(const QJsonArray &foldersData);
    
    // 同步文件数据
    bool syncFilesFromJson(const QJsonArray &filesData);
    
    // 文件夹记录操作
    bool insertFolder(const KmsFolder &folder);
    bool updateFolder(const KmsFolder &folder);
    QList<KmsFolder> queryFoldersByPath(const QString &path);
    KmsFolder queryFolderByExactPath(const QString &path);
    KmsFolder queryFolderById(const QString &folderId);
    QList<KmsFolder> queryAllFolders();
    
    // 文件夹状态管理
    QList<KmsFolder> querySubFoldersByFolderId(const QString &folderId);
    QList<KmsFile> querySubFilesByFolderId(const QString &folderId);
    int calculateFolderStatus(const QString &folderId);
    bool updateFolderStatusRecursively(const QString &folderId);
    bool updateFolderStatusByFileChange(const QString &fileId);
    
    // 公共方法：手动更新文件夹状态
    Q_INVOKABLE bool updateFolderStatus(const QString &folderId);
    
    // 文件记录操作
    bool insertFile(const KmsFile &file);
    bool updateFile(const KmsFile &file);
    bool updateFileFromJson(const QJsonObject &fileData);
    QList<KmsFile> queryFilesByPath(const QString &path);
    QList<KmsFile> queryFilesByFolderId(const QString &folderId);
    QList<KmsFile> queryAllFiles();
    KmsFile queryFileById(const QString &fileId);
    
    // 本地文件信息管理
    bool updateLocalFileInfo(const QString &fileId, qint64 localFileSize, const QString &localFileChecksum, const QString &localFilePath = QString());
    bool clearLocalFileInfo(const QString &fileId);
    
    // 更新文件状态
    bool updateFileStatus(const QString &fileId, int status);
    
    // 命令记录操作
    bool insertCommand(const KmsCommand &command);
    bool updateCommandLocalFilePath(const QString &downloadUrl, const QString &localFilePath);
    KmsCommand queryCommandByLocalFilePath(const QString &localFilePath);
    bool deleteCommandByCommitUrl(const QString &commitUrl);
    
    // 测试数据插入方法
    bool insertTestData();

signals:
    void databaseInitialized();
    
    // 文件与文件夹同步信号
    void foldersSynced();
    
    // 文件变更信号（下载完成、状态更新、本地修改等触发）
    void filesChanged();

private:
    QSqlDatabase m_database;
    QString m_databasePath;
    QString m_userWorkDirectory; // 用户工作目录
    
    // 创建表结构
    bool createTables();
    
    // 获取数据库路径
    QString getDatabasePath();
    
    // 设置用户工作目录
    void setUserWorkDirectory(const QString &workDirectory);
    
    // 检查数据库连接
    bool isDatabaseConnected();
};

#endif // DATABASEMANAGER_H
